﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using SGLisp;
public class SGTrigger
{
    public string Desc;
    protected bool IsRuning = false;
    protected int CurActioni = 0;
    protected bool IsWaitAction = false;

    public List<TriggerEvent> TriggerEvents = new List<TriggerEvent>();
    public FunctionNode ConditionNode;
    public List<BaseAction> ActionNodes;

    List<TriggerInstance> RunningInstances = new List<TriggerInstance>();

    public Context ClojureContext;

    public SGTrigger(Context context)
    {
        this.ClojureContext = new Context(context);
    }

    public virtual void OnTrigger(Hashtable argDic)
    {
        if (argDic != null)
        {
            foreach (DictionaryEntry arg in argDic)
            {
                ClojureContext.Define((string)arg.Key, (ASTNode)arg.Value);
            }
        }
        if (IsEvent(argDic) && IsCondition())
        {
            RunActions();
        }

    }
    public bool IsEvent(Hashtable argDic)
    {
        for (int i = 0; i < TriggerEvents.Count; i++)
        {
            if (TriggerEvents[i].EventCondition(argDic))
            {
                return true;
            }
        }
        return false;
    }

    public bool IsCondition()
    {
        if (ConditionNode == null)
        {
            return true;
        }
        BoolNode bnode = (BoolNode)ConditionNode.Exec(null, ClojureContext);
        return bnode.Val;
    }
    public void AddEvent(TriggerEvent triggerEvent)
    {
        this.TriggerEvents.Add(triggerEvent);
    }

    public void RunActions()
    {
        this.GetRunInstance().Run();
        if (this.IsRuning == false)
        {
            this.IsRuning = true;
            this.CurActioni = 0;
            this.IsWaitAction = false;
        }
    }
    public TriggerInstance GetRunInstance()
    {
        TriggerInstance freeInstance = null;
        for (int i = 0; i < this.RunningInstances.Count; i++)
        {
            if (this.RunningInstances[i].IsRunning == false)
            {
                freeInstance = this.RunningInstances[i];
                return freeInstance;
            }
        }
        TriggerInstance newInstance = new TriggerInstance(this);
        newInstance.trigger = this;
        this.RunningInstances.Add(newInstance);
        return newInstance;
    }

    public virtual void Update()
    {
        for (int i = 0; i < this.RunningInstances.Count; i++)
        {
            this.RunningInstances[i].Update();
        }
    }
}
